package com.gitee.wsl.ext.number

import com.gitee.wsl.base.ValueRange


/**
 * Returns this value with the specified [sourceRange] (default: `0.0..1.0`)
 * closer to its maximum value for [amount] in range `(0.0..1.0]`
 * respective closer to its minimum value for [amount] in range `[-1.0..0.0)`.
 *
 * @throws IllegalArgumentException if this value isn't in the specified [sourceRange] or [amount] isn't in `[-1.0..+1.0]`
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Double.scale(
    amount: Double,
    sourceRange: ClosedRange<Double> = ValueRange.Normalized,
): Double {
    require(this in sourceRange) { "$this must be in $sourceRange" }
    require(amount in ValueRange.Scaling) { "$this must be in ${ValueRange.Scaling}" }
    return this + amount * (if (amount > 0.0) sourceRange.endInclusive - this else this - sourceRange.start)
}

/**
 * Returns this value with the specified [sourceRangeStart] (default: `0.0`)
 * and [sourceRangeEndInclusive] (default: `1.0`)
 * closer to its maximum value [sourceRangeEndInclusive] for [amount] in range `(0.0..1.0]`
 * respective closer to its minimum value [sourceRangeStart] for [amount] in range `[-1.0..0.0)`.
 *
 * @throws IllegalArgumentException if this value isn't in the [ClosedRange]
 * starting with the specified [sourceRangeStart] and
 * ending with the specified [sourceRangeEndInclusive] or [amount] isn't in `[-1.0..+1.0]`
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Double.scale(
    amount: Double,
    sourceRangeEndInclusive: Double = ValueRange.Normalized.max,
    sourceRangeStart: Double = ValueRange.Normalized.min,
): Double = scale(amount, sourceRangeStart..sourceRangeEndInclusive)
